﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using Flurl.Http;
using Pay.Core;
using Pay.Data;
using Pay.DTO;
using Pay.IService;
using Pay.Service.Cache;
using Pay.TO;

namespace Pay.Service {
    public class GradeService : ServiceBase, IGradeService, IDisposable {
        private IUnitOfWork _iUnitOfWork;

        public GradeService(IUnitOfWork iUnitOfWork) : base(iUnitOfWork) {
            _iUnitOfWork = iUnitOfWork;
        }

        public IEnumerable<grade_dto> Gets(string merchant_no) {
            return context.Grades.Where(c => c.MerchantNo == merchant_no).OrderByDescending(c => c.Sort).FromCache<Grade, grade_dto>("Grade");
        }

        public grade_dto Get(long id) {
            return context.Grades.Where(c => c.Id == id).FromCacheFirstOrDefault(query => {
                var model = query.FirstOrDefault();
                if (model == null)
                    throw new ServerErrorException("等级不存在");
                var result = model.ToDtoObject<grade_dto>();
                return result;
            }, "Grade");
        }

        public grade_dto Get(string grade_no) {
            return context.Grades.Where(c => c.GradeNo == grade_no).FromCacheFirstOrDefault(query => {
                var model = query.FirstOrDefault();
                if (model == null)
                    throw new ServerErrorException("等级不存在");
                var result = model.ToDtoObject<grade_dto>();
                return result;
            }, "Grade");
        }

        public grade_dto Get(string grade_no, string merchant_no) {
            return context.Grades.Where(c => c.GradeNo == grade_no && c.MerchantNo == merchant_no).FromCacheFirstOrDefault(query => {
                var model = query.FirstOrDefault();
                if (model == null)
                    throw new ServerErrorException("等级不存在");
                var result = model.ToDtoObject<grade_dto>();
                return result;
            }, "Grade");
        }

        public int Add(grade_dto dto) {
            context.Grades.Add(dto.ToDtoObject<Grade>());
            return _iUnitOfWork.Commit("Grade");
        }

        public int Update(grade_dto dto) {
            var grade = context.Grades.FindById(dto.id);
              grade.GradeNo = dto.grade_no;
              grade.Name = dto.name;
              grade.Sort = dto.sort;
            return _iUnitOfWork.Commit("Grade");
;
        }

        //public int Add(grade_dto dto) {
        //    var merchant = context.Merchants.FirstOrDefault(c => c.MerchantNo == dto.merchant_no).ToDtoObject<merchant_dto>();
        //    List<merchant_payment_ex> payments = new List<merchant_payment_ex>();
        //    var model = dto.ToDtoObject<Grade>();
        //    dto.payments.DataForEach(item => {
        //        //如果比O单商户低就报错
        //        var payment = merchant.payments.FirstOrDefault(c => c.payment_id == item.payment_id);
        //        foreach (var settle in payment.settles) {
        //            var grade_settle = item.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
        //            if (grade_settle.fee < settle.fee)
        //                throw new ServerErrorException("级别的费率不能低于O单商户");
        //            if (grade_settle.settle < settle.settle)
        //                throw new ServerErrorException("级别的结算费不能低于O单商户");
        //        }
        //        model.MerchantPayments.Add(item.ToDtoObject<MerchantPayment>());
        //        //o单数据
        //        payments.Add(new merchant_payment_ex { channel = item.payment.channel, code = item.payment.code, name = item.payment.name, sort = item.sort, settles = item.payment.settles });
        //    });
        //    context.Grades.Add(model);
        //    int result = _iUnitOfWork.Commit("Grade");
        //    if (result > 0) {
        //        try {
        //            //这里是BUG，因为新增是没有异步URL的，暂时没有好办法解决
        //            var data = new grade_result { merchant_no = dto.merchant_no, name = dto.name, grade_no = dto.grade_no, payments = payments, sort = dto.sort };
        //            var dd = dto.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveString().Result.ToUpper();
        //            return result;
        //        } catch (Exception ex) {
        //            var log = IocHelper.Get<ILogHelper>("info");
        //            log.Error("新增商户级别通知失败:" + dto.merchant_no + ",no:" + dto.grade_no);
        //            log.Error(ex.Message);
        //        }
        //    }
        //    return result;
        //}

        //public int Update(grade_dto dto) {
        //    var merchant = context.Merchants.FirstOrDefault(c => c.MerchantNo == dto.merchant_no).ToDtoObject<merchant_dto>();
        //    List<merchant_payment_ex> payments = new List<merchant_payment_ex>();
        //    var model = context.Grades.FindById(dto.id);
        //    dto.ToDtoObject(model);
        //    var payment_ids = dto.payments.Select(c => c.payment_id).ToList();
        //    if (payment_ids.Count > 0) {
        //        var data_ids = model.MerchantPayments.Select(c => c.PaymentId).CopyToList();
        //        //新增
        //        payment_ids.Except(data_ids).DataForEach(filter_id => {
        //            var new_item = dto.payments.First(c => c.payment_id == filter_id);
        //            //级别的费率或结算费不能低于O单商户
        //            var payment = merchant.payments.FirstOrDefault(c => c.payment_id == new_item.payment_id);
        //            foreach (var settle in payment.settles) {
        //                var grade_settle = new_item.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
        //                if (grade_settle.fee < settle.fee)
        //                    throw new ServerErrorException("级别的费率不能低于O单商户");
        //                if (grade_settle.settle < settle.settle)
        //                    throw new ServerErrorException("级别的结算费不能低于O单商户");
        //            }
        //            model.MerchantPayments.Add(new MerchantPayment { GradeId = dto.id, Sort = new_item.sort, PaymentId = filter_id, Settles = new_item.settles.ToJson() });
        //            //o单数据
        //            payments.Add(new merchant_payment_ex {
        //                channel = new_item.payment.channel, code = new_item.payment.code, name = new_item.payment.name, sort = new_item.sort,
        //                settles = new_item.settles, bank = new_item.payment.bank, start_time = new_item.payment.start_time, end_time = new_item.payment.end_time
        //            });
        //        });
        //        //删除
        //        data_ids.Except(payment_ids).DataForEach(filter_id => {
        //            var item = model.MerchantPayments.First(c => c.PaymentId == filter_id);
        //            context.Entry(item).State = EntityState.Deleted;
        //        });
        //        //更新
        //        payment_ids.Intersect(data_ids).DataForEach(filter_id => {
        //            var new_item = dto.payments.First(c => c.payment_id == filter_id);
        //            //级别的费率或结算费不能低于O单商户
        //            var payment = merchant.payments.FirstOrDefault(c => c.payment_id == new_item.payment_id);
        //            foreach (var settle in payment.settles) {
        //                var grade_settle = new_item.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
        //                if (grade_settle.fee < settle.fee)
        //                    throw new ServerErrorException("级别的费率不能低于O单商户");
        //                if (grade_settle.settle < settle.settle)
        //                    throw new ServerErrorException("级别的结算费不能低于O单商户");
        //            }

        //            var item = model.MerchantPayments.First(c => c.PaymentId == filter_id);
        //            item.Sort = new_item.sort;
        //            item.Settles = new_item.settles.ToJson();
        //            context.Entry(item).State = EntityState.Modified;
        //            //o单数据
        //            payments.Add(new merchant_payment_ex {
        //                channel = new_item.payment.channel, code = new_item.payment.code, name = new_item.payment.name, sort = new_item.sort,
        //                settles = new_item.settles, bank = new_item.payment.bank, start_time = new_item.payment.start_time, end_time = new_item.payment.end_time
        //            });
        //        });
        //    } else {
        //        //如果原来有数据，删除
        //        if (model.MerchantPayments.Count > 0)
        //            model.MerchantPayments.DataForEach(item => { context.Entry(item).State = EntityState.Deleted; });
        //    }
        //    int result = _iUnitOfWork.Commit("Grade");
        //    if (result > 0) {
        //        try {
        //            var data = new grade_result { merchant_no = dto.merchant_no, name = dto.name, grade_no = dto.grade_no, payments = payments, sort = dto.sort };
        //            var dd = dto.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveString().Result.ToUpper();
        //            return result;
        //        } catch (Exception ex) {
        //            var log = IocHelper.Get<ILogHelper>("info");
        //            log.Error("商户级别通知失败:" + dto.merchant_no + ",no:" + dto.grade_no);
        //            log.Error(ex.Message);
        //        }
        //    }
        //    return result;
        //}

        public int Delete(long id) {
            context.Grades.Remove(id);
            int result = _iUnitOfWork.Commit("Grade");
            return result;
        }


        [Serializable]
        public class grade_data {
            /// <summary>
            /// 通道
            /// </summary>
            public PayChannel channel { get; set; }
            /// <summary>
            /// 支付方式
            /// </summary>
            public string code { get; set; }
        }
        public class grade_data_equality : IEqualityComparer<grade_data> {
            public bool Equals(grade_data x, grade_data y) {
                return x.code == y.code && x.channel == y.channel;
            }

            public int GetHashCode(grade_data obj) {
                if (obj == null) {
                    return 0;
                } else {
                    return obj.ToString().GetHashCode();
                }
            }
        }

        /// <summary>
        /// 用于商户请求修改
        /// </summary>
        /// <returns>The save.</returns>
        /// <param name="grade">Grade.</param>
        //public int Save(grade_ex grade) {
        //    var model = context.Grades.FirstOrDefault(c => c.GradeNo == grade.grade_no && c.MerchantNo == grade.merchant_no);
        //    var merchant = context.Merchants.FirstOrDefault(c => c.MerchantNo == grade.merchant_no).ToDtoObject<merchant_dto>();
        //    if (model != null) {
        //        model.Name = grade.name;
        //        model.Sort = grade.sort;
        //        model.Notify = grade.notify;
        //        var payment_ids = grade.payments.Select(c => new grade_data { code = c.code, channel = c.channel }).ToList();
        //        if (payment_ids.Count > 0) {
        //            var data_ids = model.MerchantPayments.Select(c => new grade_data { code = c.Payment.Code, channel = c.Payment.Channel }).ToList();
        //            //新增
        //            payment_ids.Except(data_ids, new grade_data_equality()).DataForEach(filter_id => {
        //                var new_item = grade.payments.First(c => c.channel == filter_id.channel && c.code == filter_id.code);
        //                var paymentType = context.Payments.First(c => c.Code == filter_id.code && c.Channel == filter_id.channel);
        //                //级别的费率或结算费不能低于O单商户
        //                var payment = merchant.payments.FirstOrDefault(c => c.payment_id == paymentType.Id);
        //                foreach (var settle in payment.settles) {
        //                    var grade_settle = new_item.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
        //                    if (grade_settle.fee < settle.fee)
        //                        throw new ServerErrorException("级别的费率不能低于O单商户");
        //                    if (grade_settle.settle < settle.settle)
        //                        throw new ServerErrorException("级别的结算费不能低于O单商户");
        //                }
        //                model.MerchantPayments.Add(new MerchantPayment {
        //                    GradeId = model.Id, PaymentId = paymentType.Id, Sort = new_item.sort, Settles = new_item.settles.ToJson()
        //                });
        //            });
        //            //删除
        //            data_ids.Except(payment_ids, new grade_data_equality()).DataForEach(filter_id => {
        //                var item = model.MerchantPayments.First(c => c.Payment.Channel == filter_id.channel && c.Payment.Code == filter_id.code);
        //                context.Entry(item).State = EntityState.Deleted;
        //            });
        //            //更新
        //            payment_ids.Intersect(data_ids, new grade_data_equality()).DataForEach(filter_id => {
        //                var new_item = grade.payments.First(c => c.channel == filter_id.channel && c.code == filter_id.code);
        //                var item = model.MerchantPayments.First(c => c.Payment.Channel == filter_id.channel && c.Payment.Code == filter_id.code);
        //                //级别的费率或结算费不能低于O单商户
        //                var payment = merchant.payments.FirstOrDefault(c => c.payment_id == item.PaymentId);
        //                foreach (var settle in payment.settles) {
        //                    var grade_settle = new_item.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
        //                    if (grade_settle.fee < settle.fee)
        //                        throw new ServerErrorException("级别的费率不能低于O单商户");
        //                    if (grade_settle.settle < settle.settle)
        //                        throw new ServerErrorException("级别的结算费不能低于O单商户");
        //                }
        //                item.Settles = new_item.settles.ToJson();
        //                context.Entry(item).State = EntityState.Modified;
        //            });
        //        } else {
        //            //如果原来有数据，删除
        //            if (model.MerchantPayments.Count > 0)
        //                model.MerchantPayments.DataForEach(item => { context.Entry(item).State = EntityState.Deleted; });
        //        }
        //    } else {
        //        model = new Grade();
        //        model.MerchantNo = grade.merchant_no;
        //        model.Name = grade.name;
        //        model.Sort = grade.sort;
        //        model.Notify = grade.notify;
        //        foreach (var grade_payment in grade.payments) {
        //            var paymentType = context.Payments.First(c => c.Code == grade_payment.code && c.Channel == grade_payment.channel);
        //            //级别的费率或结算费不能低于O单商户
        //            var payment = merchant.payments.FirstOrDefault(c => c.payment_id == paymentType.Id);
        //            foreach (var settle in payment.settles) {
        //                var grade_settle = grade_payment.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
        //                if (grade_settle.fee < settle.fee)
        //                    throw new ServerErrorException("级别的费率不能低于O单商户");
        //                if (grade_settle.settle < settle.settle)
        //                    throw new ServerErrorException("级别的结算费不能低于O单商户");
        //            }
        //            model.MerchantPayments.Add(new MerchantPayment {
        //                GradeId = model.Id, PaymentId = paymentType.Id, Sort = grade_payment.sort, Settles = grade_payment.settles.ToJson()
        //            });
        //        }
        //        context.Grades.Add(model);
        //    }
        //    int result = _iUnitOfWork.Commit("Grade");
        //    return result;
        //}
    }
}